/*
    This script is create By  @judu
    Year is 2019.
*/

const { ccclass, property } = cc._decorator;

@ccclass
export default class barToggole extends cc.Component {

    /**必填 */
    //按场景根节点
    @property({
        type: cc.Node,
        tooltip: "要切换场景节点的父节点（必须指定，否则不触发脚本）",
        displayName: "场景切换根节点",
    })
    private sceneRoot: cc.Node = null;

    //按钮根节点
    @property({
        type: cc.Node,
        displayName: "按钮激活根节点",
        tooltip: "触发切换场景的按钮根节点,且按钮数量与场景一致(必须指定，否则不触发脚本)",
    })
    private buttonRoot: cc.Node = null;

    /**辅助 */
    //初始场景
    @property({
        type: cc.Node,
        tooltip: "初始激活显示的场景节点，如果不指定则使用默认第一个！",
        displayName: "初始的场景节点",
    })
    private inItScene: cc.Node = null;

    //按钮点击音效
    @property({
        type: cc.AudioClip,
        displayName: "按钮点击音效",
        tooltip: "按钮点击切换时的音效（如果不指定则不播放）",
    })
    private touchSound: cc.AudioClip = null;

    //控制遮罩节点的显示（不显示在编辑器里）
    @property
    private _displayMaskNode = false;

    //是否使用遮罩，显示在编辑器里的代理选项（开关）
    @property({
        displayName: "使用遮罩",
        tooltip: "是否使用遮罩节点",
    })
    set isDisplayMask(value: boolean) {
        //更新
        this._displayMaskNode = value;
        //设置节点的显隐
        //@ts-ignore
        cc.Class.Attr.setClassAttr(barToggole, 'maskNode', 'visible', value);
    }
    get isDisplayMask() {
        return this._displayMaskNode;
    }

    //遮罩节点
    @property({
        type: cc.Node,
        tooltip: "场景中可以遮住其他场景的遮罩（如果不指定则不使用）",
        displayName: "遮罩",
        visible: false,
    })
    private maskNode: cc.Node = null;

    //按钮切换效果
    @property({
        displayName: "按钮切换显示",
        tooltip: "是否在点击时显示按钮切换效果"
    })
    private displayBtnToggole: boolean = false;

    //控制遮罩节点的显示（不显示在编辑器里）
    @property
    private _displayButtonEasing = false;
    //显示在编辑器里的代理选项（开关）
    @property({
        displayName: "按钮缓动动效",
        tooltip: "是否开启按钮点击时缓动的效果",
    })
    set isDisplayEasing(value: boolean) {
        //更新
        this._displayButtonEasing = value;
        //设置节点的显隐
        //@ts-ignore
        cc.Class.Attr.setClassAttr(barToggole, 'easingButtonTime', 'visible', value);
        //@ts-ignore
        cc.Class.Attr.setClassAttr(barToggole, 'easingButtonSpring', 'visible', value);
    }
    get isDisplayEasing() {
        return this._displayButtonEasing;
    }

    //缓动时间
    @property({
        displayName: "缓动时间",
        tooltip: "数值越大，时间越长",
        visible: false,
    })
    private easingButtonTime: number = 0.15;

    //缓动弹性
    @property({
        displayName: "缓动弹性",
        tooltip: "数值越大，弹性越大",
        visible: false,
    })
    private easingButtonSpring: number = 0.15;

    @property
    private _displaySceneEasing = false;

    @property({
        displayName: "选中场景缓动",
        tooltip: "是否开启选中场景的缓动过度效果",
    })
    set isDisplaySceneEasing(value: boolean) {
        //更新
        this._displaySceneEasing = value;
        //设置节点的显隐
        //@ts-ignore
        cc.Class.Attr.setClassAttr(barToggole, 'easingSceneScale', 'visible', value);
        //@ts-ignore
        cc.Class.Attr.setClassAttr(barToggole, 'easingSceneTime', 'visible', value);
    }
    get isDisplaySceneEasing() {
        return this._displaySceneEasing;
    }

    //场景放大
    @property({
        displayName: "缓动数值",
        tooltip: "场景切换选中后，缩放动画放大的倍数",
        visible: false,
    })
    private easingSceneScale: number = 1.1;

    @property({
        displayName: "缓动时间",
        tooltip: "选中场景切换后播放动画的时间",
        visible: false,
    })
    private easingSceneTime: number = 0.4;

    //场景标记
    private sceneTag: number = null;

    //遮罩顺序
    private maskIndex: number = null;

    //按钮的普通状态
    private btnNormal;

    //开始
    protected onLoad() {
        if (this.sceneRoot == null || this.buttonRoot == null) {
            //提示
            console.warn("请拖入场景切换根节点或者按钮激活根节点");
            return;
        }

        //修复取消勾选后依旧显示遮罩
        if (!this._displayMaskNode)
            this.maskNode = null;

        //记录遮罩节点
        let maskNodeUuid;
        if (this.maskNode != null)
            maskNodeUuid = this.maskNode.uuid;

        //  绑定场景和按钮
        let scenes = this.sceneRoot.children,
            buttons = this.buttonRoot.children;
        let scene, button;
        for (let i = 0, k = 0; i < scenes.length; i++) {
            scene = scenes[i];
            if (this.maskNode == null) { //无遮罩 ，一一对应
                scene.active = false;
                scene.attr({ sceneId: i });
                button = buttons[i];
                if (button) {
                    button.attr({ buttonId: i });
                    if (this.displayBtnToggole) {
                        let btnTransition = button.getComponent(cc.Button).transition;
                        switch (btnTransition) {
                            case cc.Button.Transition.NONE: // 不做任何过渡
                                console.warn("请选择按钮过度方式后再勾选按钮切换显示");
                                break;
                            case cc.Button.Transition.COLOR: // 进行颜色之间过渡
                                if (this.btnNormal == null)
                                    this.btnNormal = button.getComponent(cc.Button).normalColor;
                                button.getComponent(cc.Button).normalColor = button.getComponent(cc.Button).disabledColor;
                                break;
                            case cc.Button.Transition.SPRITE: // 进行精灵之间过渡
                                if (this.btnNormal == null)
                                    this.btnNormal = button.getComponent(cc.Button).normalSprite;
                                button.getComponent(cc.Button).normalSprite = button.getComponent(cc.Button).disabledSprite;
                                break;
                            case cc.Button.Transition.SCALE: // 进行缩放过渡
                                console.warn("在缩放模式下不适合切换！");
                                break;
                        }
                    }
                }
            } else {//有遮罩层 
                scene.active = true;
                if (scene.uuid == maskNodeUuid)
                    this.maskIndex = scene.getSiblingIndex();
                else {
                    scene.attr({ sceneId: k });
                    button = buttons[k];
                    button.attr({ buttonId: k });
                    if (this.displayBtnToggole) {
                        let btnTransition = button.getComponent(cc.Button).transition;
                        switch (btnTransition) {
                            case cc.Button.Transition.NONE: // 不做任何过渡
                                console.warn("请选择按钮过度方式后再勾选按钮切换显示");
                                break;
                            case cc.Button.Transition.COLOR: // 进行颜色之间过渡
                                if (this.btnNormal == null)
                                    this.btnNormal = button.getComponent(cc.Button).normalColor;
                                button.getComponent(cc.Button).normalColor = button.getComponent(cc.Button).disabledColor;
                                break;
                            case cc.Button.Transition.SPRITE: // 进行精灵之间过渡
                                if (this.btnNormal == null)
                                    this.btnNormal = button.getComponent(cc.Button).normalSprite;
                                button.getComponent(cc.Button).normalSprite = button.getComponent(cc.Button).disabledSprite;
                                break;
                            case cc.Button.Transition.SCALE: // 进行缩放过渡
                                console.warn("在缩放模式下不适合切换！");
                                break;
                        }
                    }
                    k++;
                }
            }
        }

        //标记场景
        let initScene = this.inItScene;
        let initId;
        if (initScene == null)
            initId = 0;
        else {
            initId = initScene[`sceneId`];
            if (initId == null)
                console.warn("请不要拖入与遮罩相同的初始节点！");
        }
        //开启标记的场景
        if (this.maskNode == null)
            this.toggoleScene(initId, this.buttonRoot.children[initId].getComponent(cc.Button));
        else
            this.toggoleIndex(initId, this.buttonRoot.children[initId].getComponent(cc.Button));

    }


    /**
     * 切换场景的显示
     * @param sceneId 要切换的场景id
     * @param btnCom 场景对应的按钮id
     */
    private toggoleScene(sceneId, btnCom) {
        //相同点击返回
        if (sceneId == this.sceneTag || sceneId == undefined) return;

        //找到对应场景
        let scenes = this.sceneRoot.children;
        let scene;
        for (let j = 0; j < scenes.length; j++) {
            scene = scenes[j];
            //改变选中
            if (scene.sceneId == sceneId) {
                scene.active = true;
                this.changeBtnNormal(btnCom);
                this.playEasingSceneAnim(scene);
                continue;
            }
            //改变上次的
            if (scene.sceneId == this.sceneTag) {
                scene.active = false;
                this.restBtnNormal();
                if (this._displaySceneEasing)
                    scene.runAction(cc.scaleTo(this.easingSceneTime, 1).easing(cc.easeOut(this.easingSceneTime)));
            }
        }
        this.sceneTag = sceneId;
    }

    /**
     * 切换的场景的index
     * @param sceneId 要切换的场景id
     * @param btnCom 场景对应的按钮id
     */
    private toggoleIndex(sceneId, btnCom) {
        //相同点击返回
        if (sceneId == this.sceneTag || sceneId == undefined) return;

        let scenes = this.sceneRoot.children;
        let sceneIndex;
        let scene;
        for (let j = 0; j < scenes.length; j++) {
            scene = scenes[j];
            if (scene.uuid == this.maskNode.uuid) continue;

            //找到场景
            if (sceneId == scene.sceneId) {
                sceneIndex = scene.getSiblingIndex();
                scene.setSiblingIndex(this.maskIndex + 1);
                this.changeBtnNormal(btnCom);
                this.playEasingSceneAnim(scene);
                continue;
            }
            if (scene.sceneId == this.sceneTag) {
                scenes[j].setSiblingIndex(sceneIndex);
                this.restBtnNormal();
                if (this._displaySceneEasing)
                    scene.runAction(cc.scaleTo(this.easingSceneTime, 1).easing(cc.easeOut(this.easingSceneTime)));
            }
        }
        this.sceneTag = sceneId;
    }

    /**
     * 改变按钮状态
     * @param btnCom 要改变按钮的按钮组件
     */
    private changeBtnNormal(btnCom) {
        if (this.displayBtnToggole)
            switch (btnCom.transition) {
                case cc.Button.Transition.NONE: // 不做任何过渡
                    console.warn("请选择按钮过度方式后再勾选按钮切换显示");
                    break;
                case cc.Button.Transition.COLOR: // 进行颜色之间过渡
                    btnCom.normalColor = this.btnNormal;
                    break;
                case cc.Button.Transition.SPRITE: // 进行精灵之间过渡
                    btnCom.normalSprite = this.btnNormal;
                    break;
                case cc.Button.Transition.SCALE: // 进行缩放过渡
                    console.warn("在缩放模式下不适合切换！");
                    break;
            }
    }

    /**
     * 恢复上一个按钮的选中的状态
     */
    private restBtnNormal() {
        if (this.displayBtnToggole) {
            let buttons = this.buttonRoot.children;
            let buttonNode;
            for (let i = 0; i < buttons.length; i++) {
                buttonNode = buttons[i];
                if (this.sceneTag == buttonNode.buttonId) {
                    switch (buttonNode.getComponent(cc.Button).transition) {
                        case cc.Button.Transition.NONE: // 不做任何过渡
                            console.warn("请选择按钮过度方式后再勾选按钮切换显示");
                            break;
                        case cc.Button.Transition.COLOR: // 进行颜色之间过渡
                            buttonNode.getComponent(cc.Button).normalColor = buttonNode.getComponent(cc.Button).disabledColor;
                            break;
                        case cc.Button.Transition.SPRITE: // 进行精灵之间过渡
                            buttonNode.getComponent(cc.Button).normalSprite = buttonNode.getComponent(cc.Button).disabledSprite;
                            break;
                        case cc.Button.Transition.SCALE: // 进行缩放过渡
                            console.warn("在缩放模式下不适合切换！");
                            break;
                    }
                    return;
                }
            }
        }
    }

    /**
     * 场景节点缓动
     * @param sceneNode 要缓动的场景节点
     */
    private playEasingSceneAnim(sceneNode) {
        let self = this;
        if (this._displaySceneEasing) {
            let scaleIn = cc.scaleTo(0.1, 1 - this.easingSceneScale);
            scaleIn.easing(cc.easeIn(this.easingSceneTime));
            let action = cc.sequence(scaleIn, cc.scaleTo(this.easingSceneTime, 1 + this.easingSceneScale).easing(cc.easeBackInOut()),
                cc.callFunc(() => {
                    sceneNode.scale = 1 + self.easingSceneScale;
                }));
            sceneNode.runAction(action);
        }
    }


    /**
     * 在场景中绑定的按钮事件
     * @param event 按钮事件
     */
    private toggoleSceneBtn(event) {
        if (this.sceneRoot == null || this.buttonRoot == null) {
            //提示
            console.warn("请拖入场景切换根节点或者按钮激活根节点");
            return;
        }
        //播放音效
        cc.audioEngine.play(this.touchSound, false, 1);
        //播放按钮缓动动画
        if (this._displayButtonEasing) {
            let scaleX = cc.scaleTo(this.easingButtonTime, 1 - this.easingButtonSpring, 1 + this.easingButtonSpring);
            scaleX.easing(cc.easeBackInOut());
            let scaleY = cc.scaleTo(this.easingButtonTime, 1 + this.easingButtonSpring, 1 - this.easingButtonSpring);
            scaleY.easing(cc.easeBackInOut());
            let action = cc.sequence(scaleX, scaleY, cc.scaleTo(this.easingButtonTime, 1, 1).easing(cc.easeBackInOut()));
            event.target.runAction(action);
        }
        //切换场景
        if (this.maskNode == undefined)
            this.toggoleScene(event.target.buttonId, event.target.getComponent(cc.Button));
        else
            this.toggoleIndex(event.target.buttonId, event.target.getComponent(cc.Button));
    }

    // protected update (dt) {}
}
